﻿Imports Microsoft.VisualBasic
Imports System.Data.Objects.ObjectContext
Imports System.Data.Objects
Imports SiiabCamarasMovil

Public Class EntityRepositorioBase(Of T As Class)
    Implements IDataRepository(Of T), IFunctionDataRepository


    ''' <summary>
    ''' The context object for the database
    ''' </summary>
    Private _context As SiiabCamarasEntities

    ''' <summary>
    ''' The IObjectSet that represents the current entity.
    ''' </summary>
    Private _objectSet As IObjectSet(Of T)

    ''' <summary>
    ''' Initializes a new instance of the DataRepository class
    ''' </summary>
    Public Sub New()
        Me.New(New SiiabCamarasEntities())
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the DataRepository class
    ''' </summary>
    ''' <param name="context">The Entity Framework ObjectContext</param>
    Public Sub New(context As ObjectContext)
        If Not context Is Nothing Then
            _context = context
            _objectSet = _context.CreateObjectSet(Of T)()
        Else
            _context = context
        End If

    End Sub

    ''' <summary>
    ''' Gets all records as an IQueryable
    ''' </summary>
    ''' <returns>An IQueryable object containing the results of the query</returns>
    Public Function Fetch() As IQueryable(Of T) Implements IDataRepository(Of T).Fetch
        Return _objectSet
    End Function

    ''' <summary>
    ''' Gets all records as an IEnumberable
    ''' </summary>
    ''' <returns>An IEnumberable object containing the results of the query</returns>
    Public Function Todos() As IEnumerable(Of T) Implements IDataRepository(Of T).Todos

        Return Fetch().AsEnumerable()
    End Function

    ''' <summary>
    ''' Finds a record with the specified criteria
    ''' </summary>
    ''' <param name="predicate">Criteria to match on</param>
    ''' <returns>A collection containing the results of the query</returns>
    Public Function Buscar(predicate As Func(Of T, Boolean)) As IEnumerable(Of T) Implements IDataRepository(Of T).Buscar
        Return _objectSet.Where(predicate)
    End Function

    ''' <summary>
    ''' Gets a single record by the specified criteria (usually the unique identifier)
    ''' </summary>
    ''' <param name="predicate">Criteria to match on</param>
    ''' <returns>A single record that matches the specified criteria</returns>
    Public Function BuscarUnico(predicate As Func(Of T, Boolean)) As T Implements IDataRepository(Of T).BuscarUnico
        Return _objectSet.Single(predicate)
    End Function

    ''' <summary>
    ''' Busca el ultimo elemento de una tabla, si la tabla esta vacia regresa nulo o nothing)
    ''' </summary>
    ''' <param name="predicate">Criterio para buscar</param>
    ''' <returns>El ulltimo elemento de una tabla con el criterio especificado</returns>
    Public Function BuscarUltimo(predicate As Func(Of T, Boolean)) As T Implements IDataRepository(Of T).BuscarUltimo
        Return _objectSet.OrderByDescending(predicate).LastOrDefault()
    End Function
    ''' <summary>
    ''' The first record matching the specified criteria
    ''' </summary>
    ''' <param name="predicate">Criteria to match on</param>
    ''' <returns>A single record containing the first record matching the specified criteria</returns>
    Public Function BuscarPrimero(predicate As Func(Of T, Boolean)) As T Implements IDataRepository(Of T).BuscarPrimero
        Return _objectSet.First(predicate)
    End Function

    ''' <summary>
    ''' Deletes the specified entitiy
    ''' </summary>
    ''' <param name="entity">Entity to delete</param>
    ''' <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>
    Public Sub Borrar(entity As T) Implements IDataRepository(Of T).Borrar
        If entity Is Nothing Then
            Throw New ArgumentNullException("entity")
        End If

        _objectSet.DeleteObject(entity)
    End Sub

    ''' <summary>
    ''' Deletes records matching the specified criteria
    ''' </summary>
    ''' <param name="predicate">Criteria to match on</param>
    Public Sub Borrar(predicate As Func(Of T, Boolean))
        Dim records As IEnumerable(Of T) = From x In _objectSet.Where(predicate)

        For Each record As T In records
            _objectSet.DeleteObject(record)
        Next
    End Sub

    ''' <summary>
    ''' Adds the specified entity
    ''' </summary>
    ''' <param name="entity">Entity to add</param>
    ''' <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>
    Public Sub Agregar(entity As T) Implements IDataRepository(Of T).Agregar
        If entity Is Nothing Then
            Throw New ArgumentNullException("entity")
        End If

        _objectSet.AddObject(entity)
    End Sub

    ''' <summary>
    ''' Adejunta la entidad especificada
    ''' </summary>
    ''' <param name="entity">Entidad a adjuntar</param>
    Public Sub Adjuntar(entity As T) Implements IDataRepository(Of T).Adjuntar
        _objectSet.Attach(entity)
    End Sub

    ''' <summary>
    ''' Guardar todos los cambios del contexto
    ''' </summary>
    Public Function GuardarCambios() As Integer Implements IDataRepository(Of T).GuardarCambios
        Return _context.SaveChanges()
    End Function

    ''' <summary>
    ''' Guarda todos los datos del contexto con opciones abiertas(SaveOptions), ideal para transacciones
    ''' </summary>
    ''' <param name="options">Opciones para guardar el contexto</param>
    Public Function GuardarCambios(options As SaveOptions) As Integer Implements IDataRepository(Of T).GuardarCambios
        Return _context.SaveChanges(options)
    End Function

    ''' <summary>
    ''' Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    ''' <summary>
    ''' Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
    ''' </summary>
    ''' <param name="disposing">A boolean value indicating whether or not to dispose managed resources</param>
    Protected Overridable Sub Dispose(disposing As Boolean)
        If disposing Then
            If _context IsNot Nothing Then
                _context.Dispose()
                _context = Nothing
            End If
        End If
    End Sub


    Public ReadOnly Property EntityObjectContext() As SiiabCamarasEntities
        Get
            Return _context
        End Get
    End Property

    ''' <summary>
    ''' GetDate Funcion Sql Server
    ''' </summary>
    ''' <returns >DateTime con la fecha actual del servidor </returns>
    Public Function GetCurrentDate() As Date Implements IFunctionDataRepository.GetCurrentDate
        Dim dtActual As New DateTime
        dtActual = _context.CreateQuery(Of DateTime)("CurrentDateTime()").AsEnumerable().FirstOrDefault()
        _context.Dispose()
        Return dtActual
    End Function

    ''' <summary>
    ''' GetDate Funcion Sql Server
    ''' </summary>
    ''' <returns >DateTime con la fecha actual del servidor </returns>
    Public Function GetCurrentDateSinHHMMSS() As Date Implements IFunctionDataRepository.GetCurrentDateSinHHMMSS
        Dim dtActual As New DateTime
        dtActual = _context.CreateQuery(Of DateTime)("CurrentDateTime()").AsEnumerable().FirstOrDefault()
        _context.Dispose()
        dtActual = Utilerias.convertirddMMyyyToDateTime(dtActual, 0, 0, 0)
        Return dtActual
    End Function
End Class